package org.yoyo.classroom.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.yoyo.classroom.result.Result;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/upload")
public class UploadController {

    @Value("${image.hosting.upload-url}")
    private String uploadUrl;

    @Value("${image.hosting.token-url}")
    private String tokenUrl;

    @Value("${image.hosting.email}")
    private String email;

    @Value("${image.hosting.password}")
    private String password;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 上传图片到图床
     */
    @PostMapping("/image")
    public Result<String> uploadImage(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return Result.error("请选择要上传的图片");
            }

            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return Result.error("只能上传图片文件");
            }

            // 构建请求体
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return UUID.randomUUID().toString() + "." + StringUtils.getFilenameExtension(file.getOriginalFilename());
                }
            };
            body.add("image", resource);

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            // 获取token
            String token = getToken();
            if (token == null) {
                log.error("无法获取图床token");
                return Result.error("图床服务异常，请联系管理员");
            }
            headers.set("token", token);

            try {
                // 发送请求
                HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
                ResponseEntity<String> response = restTemplate.exchange(
                        uploadUrl,
                        HttpMethod.POST,
                        requestEntity,
                        String.class
                );

                // 解析响应
                ObjectMapper mapper = new ObjectMapper();
                JsonNode root = mapper.readTree(response.getBody());

                if (root.get("code").asInt() == 200) {
                    String imageUrl = root.get("data").get("url").asText();
                    log.info("图片上传成功: {}", imageUrl);
                    return Result.success(imageUrl);
                } else {
                    String errorMsg = root.get("msg").asText();
                    log.error("图床返回错误: {}", errorMsg);
                    return Result.error("图床服务异常: " + errorMsg);
                }
            } catch (HttpClientErrorException e) {
                // 处理客户端错误（4xx）
                log.error("图床服务客户端错误: {}, 状态码: {}", e.getMessage(), e.getStatusCode());
                if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                    return Result.error("图床服务不可用，请联系管理员");
                }
                return Result.error("图床服务异常，请联系管理员");
            } catch (HttpServerErrorException e) {
                // 处理服务器错误（5xx）
                log.error("图床服务器错误: {}, 状态码: {}", e.getMessage(), e.getStatusCode());
                return Result.error("图床服务器异常，请联系管理员");
            } catch (ResourceAccessException e) {
                // 处理连接超时等网络错误
                log.error("无法连接到图床服务: {}", e.getMessage());
                return Result.error("无法连接到图床服务，请检查网络或联系管理员");
            }

        } catch (Exception e) {
            log.error("图片上传处理异常", e);
            return Result.error("图片上传失败: " + e.getMessage());
        }
    }

    /**
     * 获取图床token
     */
    private String getToken() {
        try {
            // 构建请求体
            MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
            body.add("email", email);
            body.add("password", password);
            body.add("refresh", "0");

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            try {
                // 发送请求
                HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
                ResponseEntity<String> response = restTemplate.exchange(
                        tokenUrl,
                        HttpMethod.POST,
                        requestEntity,
                        String.class
                );

                // 解析响应
                ObjectMapper mapper = new ObjectMapper();
                JsonNode root = mapper.readTree(response.getBody());

                if (root.get("code").asInt() == 200) {
                    String token = root.get("data").get("token").asText();
                    log.info("获取token成功");
                    return token;
                } else {
                    log.error("获取token失败: {}", root.get("msg").asText());
                    return null;
                }
            } catch (HttpClientErrorException | HttpServerErrorException | ResourceAccessException e) {
                log.error("获取token时发生错误: {}", e.getMessage());
                return null;
            }

        } catch (Exception e) {
            log.error("获取token异常", e);
            return null;
        }
    }
}